<?php

namespace hotel\common\utils;

use hotel\common\models\App;
use Yii;
use yii\log\FileTarget;

class PayServices {

//    public static $channelMerId = '123';
//    public static $appId = '2';
//    public static $channelId = 'wxb5f7fc755cfd3aeb';
//    public static $aid = '5';
//    public static $key = 'dkyG3NNCjIospBkV21T4dCJXkan9yjwW';

//    public static $callBackUrl = 'https://t.shop.raysfly.com/api/task/call-back';
//    public static $hs_pay_url = 'http://paycentre.horsevision.cn/frontend/';


    //预支付
    public static function Pay($userId,$amount,$payNo,$goodsDesc,$commodityName,$appid){
        $app_data = App::find()->where("appid = '$appid'")->asArray()->one();
        $url = \Yii::$app->params['hs_pay_url'] . "wx-pay/pre-create-order";
        $data = [];
        $data['channelMerId'] = $app_data['pay_channel_mer_id'];
        $data['appId'] = $app_data['pay_app_id'];
        $data['aid'] = $app_data['pay_aid'];
        $data['channelId'] = $app_data['pay_channel_id'];
        $data['nonceStr'] = self::getRandChar(32);
        $data['timestamp'] = time();
        $data['userId'] = $userId;
        $data['callBackUrl'] = \Yii::$app->params['call_back_url'];
        $data['amount'] = $amount;
        $data['payNo'] = $payNo;
        $data['goodsDesc'] = $goodsDesc;
        $data['commodityName'] = $commodityName;
        $data['signType'] = 'MD5';
        $data['tradeType'] = 'JSAPI';
        $data['from'] = '酒店';
        self::recordPay($data);
        $sign_str = self::computeSign($data,false,$app_data['pay_key']);
        $data['sign'] = $sign_str;
        $result = \hotel\common\utils\HttpClient::post($url, $data);
        $res = json_decode($result, true);
        if($res['code'] == 0 && $res['msg'] == 'success'){
            return $res['data'];
        }
        return false;
    }


    //预支付
    public static function Pay1($userId,$amount,$payNo,$goodsDesc,$commodityName,$appid){
        $app_data = App::find()->where("appid = '$appid'")->asArray()->one();
        $url = \Yii::$app->params['hs_pay_url'] . "wx-pay/pre-create-order";
        $data = [];
        $data['channelMerId'] = $app_data['pay_channel_mer_id'];
        $data['appId'] = $app_data['pay_app_id'];
        $data['aid'] = $app_data['pay_aid'];
        $data['channelId'] = $app_data['pay_channel_id'];
        $data['nonceStr'] = self::getRandChar(32);
        $data['timestamp'] = time();
        $data['userId'] = $userId;
        $data['callBackUrl'] = \Yii::$app->params['call_back_url'];
        $data['amount'] = $amount;
        $data['payNo'] = $payNo;
        $data['goodsDesc'] = $goodsDesc;
        $data['commodityName'] = $commodityName;
        $data['signType'] = 'MD5';
        $data['tradeType'] = 'JSAPI';
        $data['from'] = '酒店';
        self::recordPay($data);
        $sign_str = self::computeSign($data,false,$app_data['pay_key']);
        $data['sign'] = $sign_str;
        $result = \hotel\common\utils\HttpClient::post($url, $data);
        $res = json_decode($result, true);
        if($res['code'] == 0 && $res['msg'] == 'success'){
            return $res['data'];
        }
        return false;
    }

    //预支付
    public static function AliPay($userId,$amount,$payNo,$goodsDesc,$commodityName,$appid){
        $app_data = App::find()->where("appid = '$appid'")->asArray()->one();
        $url = \Yii::$app->params['hs_pay_url'] . "kly-ali-pay/trade-create";
        $data = [];
        $data['channelMerId'] = $app_data['ali_pay_channel_mer_id'];
        $data['appId'] = $app_data['ali_pay_app_id'];
        $data['aid'] = $app_data['ali_pay_aid'];
        $data['channelId'] = $app_data['ali_pay_channel_id'];
        $data['nonceStr'] = self::getRandChar(32);
        $data['timestamp'] = time();
        $data['ali_user_id'] = $userId;
        $data['callBackUrl'] = \Yii::$app->params['ali_call_back_url'];
        $data['returnUrl'] = 'http://pay.raysfly.com/frontend/pay-callback/kly-call-ali-back-url';
        $data['amount'] = $amount;
        $data['payNo'] = $payNo;
        $data['goodsDesc'] = $goodsDesc;
        $data['commodityName'] = $commodityName;
        $data['subject'] = $commodityName;
        $data['signType'] = 'MD5';
        $data['tradeType'] = 'facetoface';
        $data['from'] = '酒店';
        $data['attach'] = '支付宝小程序酒店订单';
        $sign_str = self::computeSign($data,false,$app_data['ali_pay_key']);
        $data['sign'] = $sign_str;
        self::recordPay($data);
        $result = \hotel\common\utils\HttpClient::post($url, $data);
        $res = json_decode($result, true);
        if($res['code'] == 0 && $res['msg'] == 'success'){
            return $res['data'];
        }
        return false;
    }

    //退款
    public static function refundOrder($userId,$amount,$payNo,$refund_amount,$appid){
        $app_data = App::find()->where("appid = '$appid'")->asArray()->one();
        $url =  \Yii::$app->params['hs_pay_url'] . "wx-pay/refund-order";
        $data = [];
        $data['channelMerId'] = $app_data['pay_channel_mer_id'];
        $data['appId'] = $app_data['pay_app_id'];
        $data['aid'] = $app_data['pay_aid'];
        $data['channelId'] = $app_data['pay_channel_id'];
        $data['payUserId'] = $userId;
        $data['nonceStr'] = self::getRandChar(32);
        $data['timeStamp'] = time();
        $data['payUserSerial'] = $payNo;
        $data['totalFee'] = $amount;
        $data['refundFee'] = $refund_amount;
        $data['signType'] = 'MD5';
        $data['refundType'] = 'moon';
        $sign_str = self::computeSign($data,false,$app_data['pay_key']);
        $data['sign'] = $sign_str;
        $result = self::curlPost($url, $data);
        $res = json_decode($result, true);
        return $res;
    }

    //预支付
    public static function activityPay($userId,$amount,$payNo,$goodsDesc,$commodityName){
        $url = \Yii::$app->params['hs_pay_url'] . "wx-pay/pre-create-order";
        $data = [];
        $data['channelMerId'] = 'QZB2020915';
        $data['appId'] = 'HOTEL2020ChX09wc15';
        $data['aid'] = 2;
        $data['channelId'] = 'wxb5f7fc755cfd3aeb';
        $data['nonceStr'] = self::getRandChar(32);
        $data['timestamp'] = time();
        $data['userId'] = $userId;
        $data['callBackUrl'] = \Yii::$app->params['activity_call_back_url'];
        $data['amount'] = $amount;
        $data['payNo'] = $payNo;
        $data['goodsDesc'] = $goodsDesc;
        $data['commodityName'] = $commodityName;
        $data['signType'] = 'MD5';
        $data['tradeType'] = 'JSAPI';
        $data['from'] = '活动';
        self::recordPay($data);
        $sign_str = self::computeSign($data,false,'ijgEEtPY31nLov6f1AvLmhrFlQuQzWNS');
        $data['sign'] = $sign_str;
        $result = \hotel\common\utils\HttpClient::post($url, $data);
        $res = json_decode($result, true);
        if($res['code'] == 0 && $res['msg'] == 'success'){
            return $res['data'];
        }
        return false;
    }

    /*
    计算签名
    $param      参数
    $sign       返回值
    */
    public static function computeSign($paraMap, $urlEncode = false,$key)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        $sign = strtoupper(md5(base64_encode($reqPar . "&key=" .$key)));
        return $sign;
    }

    public static  function recordPay($options)
    {
        $log = new FileTarget();
        $log->logFile = \Yii::$app->getRuntimePath() . '/logs/pay_' . date('Ymd') . '.log';
        $log->messages[] = [
            json_encode($options)
        ];
        $log->export();
    }

    /**
     * 生成随机字符串
     *
     * @param integer $length
     * @return void
     */
    public static function getRandChar($length = 6)
    {
        $str = null;
        $strPol = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $max = strlen($strPol) - 1;

        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol[rand(0, $max)]; //rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
    }


    public static function curlPost($url, $param, $method = 'post', $extra = [])
    {
        $calculate_time1 = microtime(true);
        $headers = $extra['headers'];
        // 初始华
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_CERTINFO, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        //curl_setopt($curl, CURLOPT_VERBOSE, true); //打印日志

        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);//函数中加入下面这条语句

        if (isset(\Yii::$app->params['curl']) && isset(\Yii::$app->params['curl']['timeout'])) {
            curl_setopt($curl, CURLOPT_TIMEOUT, \Yii::$app->params['curl']['timeout']);
        } else {
            curl_setopt($curl, CURLOPT_TIMEOUT, 5);
        }

        if (array_key_exists("HTTP_USER_AGENT", $_SERVER)) {
            curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        }

        if (!empty($headers)) {
            $headerArr = [];
            foreach ($headers as $n => $v) {
                $headerArr[] = $n . ': ' . $v;
            }
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArr);  //构造IP
        }

//    if ($cookie) {
//      curl_setopt($curl, CURLOPT_COOKIE, $cookie);
//    }


        // post处理
        if ($method == 'post') {
            curl_setopt($curl, CURLOPT_POST, true);
            if (is_array($param)) {
                $param = http_build_query($param);
            }

            curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
        } else {
            curl_setopt($curl, CURLOPT_POST, false);
        }

        // 执行输出
        $info = curl_exec($curl);

        //log
        $_errno = curl_errno($curl);
        $_error = '';
        if ($_errno) {
            $_error = curl_error($curl);
        }
        curl_close($curl);
        $calculate_time_span = microtime(true) - $calculate_time1;
        $log = \Yii::$app->getRuntimePath() . DIRECTORY_SEPARATOR . 'curl.log';
        file_put_contents($log, date('Y-m-d H:i:s') . " [ time:{$calculate_time_span} ] url: {$url} \nmethod: {$method} \ndata: " . json_encode($param) . " \nresult: {$info} \nerrorno: {$_errno} error: {$_error} \n", FILE_APPEND);

        if ($_error) {
            return $_error;
        }

        return $info;
    }

}